package org.dy.servlet.mvc.freemarker;

import java.io.IOException;
import java.io.Writer;
import java.util.Properties;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.dy.servlet.mvc.*;

import freemarker.ext.jsp.TaglibFactory;
import freemarker.ext.servlet.FreemarkerServlet;
import freemarker.ext.servlet.HttpRequestParametersHashModel;
import freemarker.ext.servlet.HttpSessionHashModel;
import freemarker.template.ObjectWrapper;

public class TemplateController extends Controller {

	private static final long serialVersionUID = 1L;

	private static final String TEMPLATE_DIR_CONFIG_KEY = "template-dir";


	private static final String DEAULT_TEMPLATE_DIR = "/WEB-INF/ftl";

	private static final String DEAULT_TEMPLATE_SUFFIX = ".ftl";

	private static final String JSP_TAG_LIB = FreemarkerServlet.KEY_JSP_TAGLIBS;

	private TemplateHandler th;

	private String templateDir;

	@Override
	public void init(ServletConfig config) throws ServletException {
		// TODO Auto-generated method stub
		super.init(config);
		templateDir = config.getInitParameter(TEMPLATE_DIR_CONFIG_KEY);
		if (templateDir == null)
			templateDir = DEAULT_TEMPLATE_DIR;
		
		ServletContext context = config.getServletContext();
		initialize(context);
	}

	protected void initialize(ServletContext context) {
		th = new TemplateHandler(context, templateDir);
		// jsp tag support
		th.setTaglib(new TaglibFactory(context));
	}

	@Override
	protected void renderView(HttpServletRequest request,
			HttpServletResponse response, ModelAndView view)
			throws IOException, ServletException {

		if (view == null)
			return;

		Writer writer = response.getWriter();

		if (view.getMsg() != "") {
			// ��ʾ������Ϣ
			writer.write(view.getMsg());
		} else if (view.getView() != "") {
			// ��session��request��Χ�ڵı��ŵ�map��
			// ${Session.yourAttribute}${RequestParameters.yourParameter}
			view.addObject(FreemarkerServlet.KEY_SESSION, buildSessionModel(
					request, response));
			view.addObject(FreemarkerServlet.KEY_REQUEST_PARAMETERS,
					new HttpRequestParametersHashModel(request));

			view.addObject(JSP_TAG_LIB, this.th.taglib);
			
			// i18n
			Properties langProp = new Properties();
			view.addObject("lang", langProp);

			try {
				// show ftl file
				if (view.getView().endsWith(DEAULT_TEMPLATE_SUFFIX))
					this.th.printOut(view.getMap(), writer, view.getView());
				else if (view.getView().indexOf(".") == -1)
					this.th.printOut(view.getMap(), writer, view.getView()
							+ DEAULT_TEMPLATE_SUFFIX);
				else
					response.sendRedirect(view.getView());
			} catch (Exception e) {
				// e.printStackTrace();
				writer.write(e.getMessage());
//				throw new ServletException(e);
			}
		} else {
			// ��ʾ������Ϣ
			writer.write(NO_ACTION);
		}
		// �ر������
		writer.flush();
		writer.close();

	}
	

	protected ObjectWrapper getObjectWrapper() {
		ObjectWrapper ow = th.getConfiguration().getObjectWrapper();
		return (ow != null ? ow : ObjectWrapper.DEFAULT_WRAPPER);
	}

	private HttpSessionHashModel buildSessionModel(HttpServletRequest request,
			HttpServletResponse response) {
		HttpSession session = request.getSession(false);
		if (session != null) {
			return new HttpSessionHashModel(session, getObjectWrapper());
		} else {
			return new HttpSessionHashModel(null, request, response,
					getObjectWrapper());
		}
	}

}
